~resetOsc = {
	SwingOSC.default.quit;
	SwingOSC.program = "/usr/local/bin/SwingOSC.jar";
	SwingOSC.default.options.javaOptions =
	"-Dswing.defaultlaf=javax.swing.plaf.metal.MetalLookAndFeel";
};
/*
~resetOsc.();
*/

~joyous = LogJoy.new;

RelativeMotion.initClass().start();

Routine { fork {
	var win, leftHand, rightHand, bg0, warpImage, sliders, rel, joys, sticks,
	syn;
	SwingOSC.default.boot;
	2.wait;
	"swingosc BOOT".postln;
	s.boot;
	2.wait;
	"server BOOT".postln;
	~joys = ~joyous.sticks.flatten;
	~sticks = 4.collect{ Bus.control };
	win = Game.new( "J O Y", 800, 480 );
	
	leftHand = Sprite.new( [ JSCImage.open( "/home/justin/leftHand.png" ) ] );
	rightHand = Sprite.new( [ JSCImage.open( "/home/justin/rightHand.png" ) ] );
	bg0 = Sprite.new( [ JSCImage.open( "/home/justin/MacLow.png" ) ] );
	warpImage = Sprite.new( [ JSCImage.open( "/home/justin/warp.png" ) ] );
	warpImage.x = 0;
	warpImage.y = 30;
	warpImage.scale = [ 0.2, 0.2 ];
	win.addSprite( leftHand, 1000 );
	win.addSprite( rightHand, 1000 );
	win.addSprite( bg0, 500 );
	win.addSprite( warpImage, 250 );
	~sliders = [
		{ | v | leftHand.x = v*( win.width - leftHand.width ); win.refresh },
		{ | v | leftHand.y = v*( win.height - leftHand.height ); win.refresh },
		{ | v | rightHand.x = v*( win.width - rightHand.width ); win.refresh },
		{ | v | rightHand.y = v*( win.height - rightHand.height ); win.refresh }
	];
	~rel = [ \x0, \y0, \x1, \y1 ].collect{ | sym, x |
		RelativeMotion(
			{ | v, d, c |
				~sticks[ x ].set( v );
				~sliders[ x ].value( v ) },
			~joys[ x ],
			sym
		);
	};
	SynthDef( \blurg, { | freq = 0.5, amp = 0.5, mod = 0.5, mod2 = 0.5 |
		Out.ar( [ 0, 1 ],
			SinOsc.ar(
				\freq.asSpec.map( Lag.kr( freq ) )
				* SinOsc.ar( \freq.asSpec.map( Lag.kr( mod ) ), 0,
					\freq.asSpec.map( Lag.kr( mod2 ) ) ),
				[ \amp.asSpec.map( Lag.kr( amp ) ),
					\amp.asSpec.map( ( 1 - Lag.kr( amp ) ).abs ) ] ) ) }
	).send(s);
	1.wait;
	~syn = Synth( \blurg );
	[ \freq, \amp, \mod, \mod2 ].do{ | k, i |
		~syn.map( k, ~sticks[ i ] );
	};
} }.play;

